package com.sunday.common.netty.e4_TCP.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class TcpClientHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        log.info("[Client]channelRead0 -> Channel 读取数据时触发");
        log.info("[Client]: {}", msg);
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelRegistered -> Channel 注册到它的 EventLoop（即它的生命周期开始）时触发。");
        // ctx.channel().closeFuture().addListener -> Channel 关闭时触发。
        ctx.channel().closeFuture().addListener(future -> log.info("[Client]channel close."));
    }


    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelUnregistered -> Channel 从它的 EventLoop 注销并且它的所有资源被释放时触发。");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelActive -> Channel 的连接建立时触发。");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelInactive -> Channel 的连接关闭时触发。");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("[Client]channelRead -> Channel 读取数据时触发");
        // 当消息被传递给 channelRead0 方法时，SimpleChannelInboundHandler 会负责自动释放处理完的消息对象，这减轻了用户的负担，因为不再需要手动释放消息。
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelReadComplete -> Channel 读取数据完成时触发");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("[Client]userEventTriggered -> Channel 处理器的生命周期中发生异常时触发");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        log.info("[Client]channelWritabilityChanged -> Channel 可写性改变时触发");
    }

    @Override
    @SuppressWarnings("deprecation")
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        log.info("[Client]exceptionCaught -> Channel 处理器的生命周期中发生异常时触发");
        log.error(cause.toString(), cause);
        ctx.close();
    }

}
